import 'dart:convert' as convert;

import 'package:dio/dio.dart';
import "package:get/get.dart" as G;

import '../../components/status/toast.dart';
import '../../config/base.dart';
import '../../model/bean/login_info.dart';
import '../../router/router.dart';
import 'error_type.dart';

/*
class Http {
  static Dio _dio;

  static String _baseUrl;
  static String _isJsonData;

  // 配置 Dio 实例
  static BaseOptions _options = BaseOptions(
    connectTimeout: 5000,
    receiveTimeout: 3000,
    headers: {"content-type": "application/x-www-form-urlencoded"},
  );

  // 单例
  Http._();

  Http._internal() {
    // 创建 Dio 实例
    _dio = Dio(_options);

    // 添加拦截器
    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (RequestOptions options) {
          // 基础请求地址
          options.baseUrl = _baseUrl;

          // 设置formData格式
          if (options.method == 'POST')
            options.data = FormData.fromMap(options.data);

          // 设置token  LoginInfo.token
          options.headers["token"] =
              LoginInfo.token != null ? LoginInfo.token : "";

          // 设置JSON提示格式
//          if (isJosn) options.data = convert.jsonEncode(options.data);

          print(options);
          print(options.baseUrl);
          print(options.data);
          print(options.path);

          // 返回结果
          return options;
        },
        onResponse: (Response response) {
          return response;
        },
        onError: (DioError e) {
          return e;
        },
      ),
    );
  }

  factory Http() => _instance;
  static Http _instance = Http._internal();

  /// 请求核心函数
  /// * [path] 请求路径|必填
  /// * [method] 请求方法|必填
  /// * [params|data] 请求参数|选填
  /// * [isJson] 数据格式|选填
  static _request(
    String path, {
    String method,
    Map<String, dynamic> params,
    Map<String, dynamic> data,
    bool isJosn,
    String otherPath,
  }) async {
    // 添加拦截
//    _addInterceptors(isJosn, otherPath: otherPath);

    // 设置基础地址
    if (otherPath != null) {
      _baseUrl = otherPath;
    } else {
      _baseUrl = BaseConfig.BASEURL.REQUEST["m1"];
    }

    // 设置JSON提示格式
//    if (isJosn) _isJsonData = convert.jsonEncode(data);

    print("11111");
    print(data);
    print(data is Map);
    print("11111");

    try {
      Response res = await _dio.request(
        path,
        data: data,
        options: Options(method: method),
      );

      print(res);
      print(";;");

      if (res.statusCode == 200 || res.statusCode == 201) {
        // 请求完成并无错误
        if (res.data['code'] == 1) {
          if (res.data is Map) {
            return HttpResponse.fromJson(res.data);
          } else {
            return convert.jsonDecode(res.data.toString());
          }
        } else if (res.data['code'] == 4004) {
          // token无效
          Toast.fail(title: res.data['msg']);
          print('token无效，状态码为：${res.data['code']},报错信息：${res.data['msg']}');
        } else {
          // 业务错误
          Toast.fail(title: res.data['msg']);
          print('服务器错误，状态码为：${res.data['code']},报错信息：${res.data['msg']}');
        }
      } else {
        // 业务错误
        Toast.fail(title: ErrorType.handleHttpError(res.statusCode));
        print('业务错误,报错信息：${ErrorType.handleHttpError(res.statusCode)}');
      }
    } on DioError catch (e) {
      // 逻辑错误
      Toast.fail(title: ErrorType.dioError(e));
      print('逻辑错误,报错信息：${ErrorType.dioError(e)}');
    }
  }

  // 添加拦截器
  static _addInterceptors(bool isJosn, {String otherPath}) {
    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (RequestOptions options) {
          // 设置基础地址
          if (otherPath != null) {
            options.baseUrl = otherPath;
          } else {
            options.baseUrl = BaseConfig.BASEURL.REQUEST["m1"];
          }

          // 设置formData格式
          if (options.method == 'POST')
            options.data = FormData.fromMap(options.data);

          // 设置token  LoginInfo.token
          options.headers["token"] =
              LoginInfo.token != null ? LoginInfo.token : "";

          // 设置JSON提示格式
          if (isJosn) options.data = convert.jsonEncode(options.data);

          // 返回结果
          return options;
        },
        onResponse: (Response response) {
          return response;
        },
        onError: (DioError e) {
          return e;
        },
      ),
    );
  }

  /// GET请求
  /// * [path] 请求路径|String|必填
  /// * [params] 请求参数|Map|选填
  /// * [isJson] 是否启用json数据格式|bool|选填
  static get(
    String path, {
    Map params,
    bool isJson = false,
    String otherPath,
  }) {
    // 执行请求
    return _request(
      path,
      method: 'GET',
      params: params,
      isJosn: isJson,
      otherPath: otherPath,
    );
  }

  /// POST请求
  /// * [path] 请求路径|String|必填
  /// * [params|data] 请求参数|Map|选填
  /// * [isJson] 是否启用json数据格式|bool|选填
  static post(
    String path, {
    Map<String, dynamic> params,
    Map<String, dynamic> data,
    bool isJson = false,
    String otherPath,
  }) {
    // 执行请求
    return _request(
      path,
      method: 'POST',
      params: params,
      data: data,
      isJosn: isJson,
      otherPath: otherPath,
    );
  }
}

class HttpResponse {
  int _code;

  String _msg;

  dynamic _data;

  bool get isSuccess => _code == 1;

  HttpResponse.fromJson(Map result) {
    this._code = result["code"];
    this._msg = result["msg"];
    this._data = result["data"]; // != null ? result["data"] : {}
  }

  int get code => _code;

  String get msg => _msg;

  dynamic get data => _data;

  @override
  String toString() {
    return "HttpResponse{code: $code, msg: $msg, data: $data}";
  }
}
*/

class Http {
  Dio _dio;

  // 默认基础路径
  String _prefix = BaseConfig.BASEURL.REQUEST["m1"];

  // 外界无法实例化
  Http._();

  // 实例化Http
  factory Http() => _instance;

  // 初始化配置
  static Http _instance = Http._internal();

  ///通用全局单例，第一次使用时初始化
  Http._internal() {
    if (_dio == null) {
      // 配置基础路径
      _dio = Dio(BaseOptions(baseUrl: _prefix, connectTimeout: 10000));

      // 拦截器
      _dio.interceptors.add(
        InterceptorsWrapper(
          onRequest: (RequestOptions options) async {
            options.headers["token"] =
                LoginInfo.token != null ? LoginInfo.token : "";
            return options;
          },
          onResponse: (Response response) async {
            HttpResponse res = HttpResponse.fromJson(response.data);
            if (!res.isSuccess) throw res;
          },
        ),
      );
    }
  }

  // 用于指定特定域名
  // 例如：两台服务器可以通过传递参数方式修改基础路径
  Http _baseUrl(String baseUrl) {
    if (_dio != null) {
      _dio.options.baseUrl = baseUrl;
    }
    return this;
  }

  // 默认域名
  Http _normal() {
    if (_dio != null) {
      if (_dio.options.baseUrl != BaseConfig.BASEURL.REQUEST["m1"]) {
        _dio.options.baseUrl = BaseConfig.BASEURL.REQUEST["m1"];
      }
    }
    return this;
  }

  /// 暴露的实例
  /// #### [base_url] String|选填|基础路径
  static Http getInstance({String baseurl}) =>
      baseurl == null ? _instance._normal() : _instance._baseUrl(baseurl);

  /// ### 通用的POST请求
  /// #### [api] String|必填|请求路径
  /// #### [params] String|选填|请求的参数
  post(api, {Map<String, dynamic> params}) async {
    Response res;

    // 注：业务错误，逻辑错误走catch中
    try {
      res = await _dio.post(api, data: FormData.fromMap(params));
      return _analysis(res);
    } on DioError catch (e) {
      if (e.error is HttpResponse) {
        // 业务异常
        Toast.fail(title: e.error.msg);
        // 跳转登录页面
        if (e.error.code == 4004) G.Get.offAllNamed(AppRoutes.Login);
      } else {
        // 逻辑异常
        Toast.fail(title: ErrorType.dioError(e));
        print('逻辑错误,报错信息：${ErrorType.dioError(e)}');
      }
    }
  }

  /// ### 上传文件（图片、txt等）
  /// #### [api] String|必填|请求路径
  /// #### [params] String|选填|请求的参数
  uploadfile(api, {FormData params}) async {
    Response res;

    // 注：业务错误，逻辑错误走catch中
    try {
      res = await _dio.post(api, data: params); // 注：考虑选取图片的第三方库差异此处文件格式在外界转化
      return _analysis(res);
    } on DioError catch (e) {
      if (e.error is HttpResponse) {
        // 业务异常
        Toast.fail(title: e.error.msg);
        // 跳转登录页面
        if (e.error.code == 4004) G.Get.offAllNamed(AppRoutes.Login);
      } else {
        // 逻辑异常
        Toast.fail(title: ErrorType.dioError(e));
        print('逻辑错误,报错信息：${ErrorType.dioError(e)}');
      }
    }
  }

  ///通用的GET请求
  /// * [api] 必填|请求路径（注：）
  /// * [params] 选填|请求的参数
  get(api, {Map<String, dynamic> params}) async {
    Response res;

    try {
      res = await _dio.get(api, queryParameters: params);
      return _analysis(res);
    } on DioError catch (e) {
      if (e.error is HttpResponse) {
        // 业务异常
        Toast.fail(title: e.error.msg);
        // 跳转登录页面
        if (e.error.code == 4004) G.Get.offAllNamed(AppRoutes.Login);
      } else {
        // 逻辑异常
        Toast.fail(title: ErrorType.dioError(e));
        print('逻辑错误,报错信息：${ErrorType.dioError(e)}');
      }
    }
  }

  /*
   使用后再编辑

  /// ### 通用的jsonMap请求
  /// #### [api] String|必填|请求路径
  /// #### [params] String|选填|请求的参数
  /// #### [allResult] bool|选填|是否获取全部的返回结果
  /// #### allResult - 注 false：只获取data中的数据，true：{code：0，data：xx，msg：xx}）
  jsonMap(api, {Map<String, dynamic> params, bool allResult = false}) async {
    Response response;
    try {
      response = await _dio.post(api, data: convert.jsonEncode(params));
      // 将数据进行加工并返回外界
      //return _dataProcessingFactory(response.data);
      return allResult ? response.data : response.data["data"];
    } on DioError catch (e) {
//      if (e.error is HttpResponse) {
//        throw HttpError.businessError(e.error);
//      } else {
//        throw HttpError.requestFial(e.type);
//      }
    }
  }



  */

  // 分析请求结果
  // * [res] Response|请求返回的结果|必填
  HttpResponse _analysis(Response res) {
    if (res.statusCode == 200 || res.statusCode == 201) {
      // 请求完成并无错误
      if (res.data['code'] == 1) {
        if (res.data is Map) {
          return HttpResponse.fromJson(res.data);
        } else {
          return convert.jsonDecode(res.data.toString());
        }
      } else if (res.data['code'] == 4004) {
        // token无效
        Toast.fail(title: res.data['msg']);
        print('token无效，状态码为：${res.data['code']},报错信息：${res.data['msg']}');
      } else {
        // 业务错误
        Toast.fail(title: res.data['msg']);
        print('服务器错误，状态码为：${res.data['code']},报错信息：${res.data['msg']}');
      }
    } else {
      // 业务错误
      Toast.fail(title: ErrorType.handleHttpError(res.statusCode));
      print('业务错误,报错信息：${ErrorType.handleHttpError(res.statusCode)}');
    }
  }
}

/// 返回结果内容修饰
class HttpResponse {
  int _code;

  String _msg;

  dynamic _data;

  bool get isSuccess => _code == 1;

  HttpResponse.fromJson(Map result) {
    this._code = result["code"];
    this._msg = result["msg"];
    this._data = result["data"];
  }

  int get code => _code;

  String get msg => _msg;

  dynamic get data => _data;

  @override
  String toString() {
    return "HttpResponse{code: $code, msg: $msg, data: $data}";
  }
}
